package com.cetc.cloud.kmga.util;

import org.apache.commons.lang.StringUtils;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * 日期操作工具类
 *
 * @author xutao
 * @version V1.0 创建时间：2017-02-15 14:28
 *          Copyright 2017 by CETC
 */
public class DateUtils {

    public static final String DATE_FORMAT_1 = "yyyy-MM-dd";
    public static final String DATE_FORMAT_2 = "yyyy-MM-dd HH:mm:ss";
    public static final String DATE_FORMAT_8 = "yyyy年MM月dd";
    public static final String DATABASE_DATE_FORMAT_1 = "yyyy-MM-dd hh24:mi:ss";
    public static final String DATE_FORMAT_3 = "HH:mm:ss";
    public static final String DATE_FORMAT_4 = "yyyy.MM.dd";
    public static final String DATE_FORMAT_5 = "yyyy-MM-dd HH";
    public static final String DATE_FORMAT_6 = "yyyyMMddHHmmss";
    public static final String DATE_FORMAT_7 = "yyyy-MM-dd HH:mm";
    public static final String DATE_FORMAT_9 = "yyyy-MM";
    public static final String DATE_FORMAT_10 = "yyyyMM";
    public static final String CONNECTOR_1 = ",";
    public static final String CONNECTOR_2 = ":";
    public static final String MAX_SECONDS = " 23:59:59";
    public static final String MIN_SECONDS = " 00:00:00";


    private static transient int gregorianCutoverYear = 1582;
    /**
     * 闰年中的每月天数
     */
    private static final int[] DAYS_P_MONTH_LY = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    /**
     * 非闰年中的每月天数
     */
    private static final int[] DAYS_P_MONTH_CY = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    private static final String CURRNET_DATA = "yyyy-MM-dd";
    /**
     * 代表数组里面的年月日
     */
    private static final int Y = 0, M = 1, D = 2;

    /**
     * 获取当前的时间
     *
     * @return
     */
    public static String getCurrnetData() {
        Date data = new Date( );
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(CURRNET_DATA);
        return simpleDateFormat.format(data);
    }

    public static List<String> getBetweenDatas(String startDate, String endDate) {
        long days = countDay(startDate, endDate);
        int[] ymd = splitYMD(startDate);
        List<String> ereryDays = new ArrayList<String>( );
        ereryDays.add(startDate);
        for (int i = 0; i < days; i++) {
            ymd = addOneDay(ymd[Y], ymd[M], ymd[D]);
            ereryDays.add(formatYear(ymd[Y]) + "-" + formatMonthDay(ymd[M]) + "-" + formatMonthDay(ymd[D]));
        }
        return ereryDays;
    }

    /**
     * 将不足两位的月份或者日期补足为两位
     *
     * @param decimal
     * @return
     */
    public static String formatMonthDay(int decimal) {
        DecimalFormat df = new DecimalFormat("00");
        return df.format(decimal);
    }


    /**
     * 获取当前时间 格式：yyyy-MM-dd HH:mm:ss
     *
     * @return
     */
    public static String getTime() {
        return format(new Date( ), DATE_FORMAT_2);
    }

    /**
     * 将不足四位的年份补足为四位
     *
     * @param decimal
     * @return
     */
    public static String formatYear(int decimal) {
        DecimalFormat df = new DecimalFormat("0000");
        return df.format(decimal);
    }

    /**
     * 检查传入的参数代表的年份是否为闰年
     *
     * @param year
     * @return
     */
    public static boolean isLeapYear(int year) {
        return year > gregorianCutoverYear ? ((year % 4 == 0) && ((year % 100 == 0) || (year % 400 == 0))) : (year % 4 == 0);
    }

    /**
     * 日期加1天
     *
     * @param year
     * @param month
     * @param day
     * @return
     */
    public static int[] addOneDay(int year, int month, int day) {
        if (isLeapYear(year)) {
            day++;
            if (day > DAYS_P_MONTH_LY[month - 1]) {
                month++;
                if (month > 12) {
                    year++;
                    month = 1;
                }
                day = 1;
            }
        } else {
            day++;
            if (day > DAYS_P_MONTH_CY[month - 1]) {
                month++;
                if (month > 12) {
                    year++;
                    month = 1;
                }
                day = 1;
            }
        }
        int[] ymd = {year, month, day};
        return ymd;
    }

    /**
     * 计算两日期之间的天数
     *
     * @param startDate
     * @param endDate
     * @return
     */
    public static long countDay(String startDate, String endDate) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(CURRNET_DATA);
        Date beginDate, edDate;
        long day = 0;
        try {
            beginDate = simpleDateFormat.parse(startDate);
            edDate = simpleDateFormat.parse(endDate);
            day = (edDate.getTime( ) - beginDate.getTime( )) / (24 * 60 * 60 * 1000);
        } catch (Exception e) {
            e.printStackTrace( );
        }
        return day;
    }

    /**
     * 将代表日期的字符串分割为代表年于日的整形数组
     *
     * @param date
     * @return
     */
    public static int[] splitYMD(String date) {
        date = date.replace("-", "");
        int[] ymd = {0, 0, 0};
        ymd[Y] = Integer.parseInt(date.substring(0, 4));
        ymd[M] = Integer.parseInt(date.substring(4, 6));
        ymd[D] = Integer.parseInt(date.substring(6, 8));
        return ymd;
    }

    /**
     * 日期字符串转换成date
     *
     * @param dateStr 日期自负串
     * @param pattern 日期格式
     * @return
     */
    public static Date parse(String dateStr, String pattern) {
        Date date = null;
        try {
            date = StringUtils.isBlank(dateStr) ? null : new SimpleDateFormat(pattern).parse(dateStr);
        } catch (ParseException pe) {
            date = null;
            pe.printStackTrace( );
        }
        return date;
    }

    /**
     * 将指定格式的日期类型转为字符串
     *
     * @param date    日期
     * @param pattern 格式
     * @return
     */
    public static String format(Date date, String pattern) {
        return date == null ? "" : new SimpleDateFormat(pattern).format(date);
    }

    /**
     * 按照yyyy-MM-dd HH:mm:ss格式,格式化日期
     *
     * @param date 日期
     * @return
     */
    public static String defaultFormat(Date date) {
        return date == null ? "" : new SimpleDateFormat(DATE_FORMAT_2).format(date);
    }

    /**
     * 得到几天前的日期
     *
     * @param date 某个日期
     * @param day  天数
     * @return
     */
    public static Date getDateBefore(Date date, int day) {
        Calendar now = Calendar.getInstance( );
        now.setTime(date);
        now.set(Calendar.DATE, now.get(Calendar.DATE) - day);
        return now.getTime( );
    }

    /**
     * 得到今天以前的日期
     *
     * @param day 天数
     * @return
     */
    public static Date getTodayBefore(int day) {

        return getDateBefore(new Date( ), day);
    }

    /**
     * 取得某天的起始时间
     *
     * @param date 日期
     * @return
     */
    public static Date getDayStartTime(Date date) {
        String dateStr = format(date, DATE_FORMAT_1) + " 00:00:00";
        return parse(dateStr, DATE_FORMAT_2);
    }

    /**
     * 取得某天的终止时间
     *
     * @param date 日期
     * @return
     */
    public static Date getDayEndTime(Date date) {
        String dateStr = format(date, DATE_FORMAT_1) + " 23:59:59";
        return parse(dateStr, DATE_FORMAT_2);
    }

    /**
     * 得到某个日期几个月之前的日期
     *
     * @param date  日期
     * @param month 月份数
     * @return
     */
    public static Date getMonthBefore(Date date, int month) {
        Calendar now = Calendar.getInstance( );
        now.setTime(date);
        now.set(Calendar.MONTH, now.get(Calendar.MONTH) - month);
        return now.getTime( );
    }

    /**
     * 获取当前天某个月份的起始值
     *
     * @param month
     * @return
     */
    public static String getTodayMonthBeforeStartStr(int month) {

        Date beforeDate = getTodayMonthBefore(month);
        String startTime = format(beforeDate, DATE_FORMAT_9) + "-01 00:00:00";
        return startTime;
    }


    /**
     * 获取当前天几个月之前的日期
     *
     * @param month
     * @return
     */
    public static String getTodayMonthBeforeEndStr(int month) {

        Date beforeDate = getTodayMonthBefore(month - 1);
        String startTime = format(beforeDate, DATE_FORMAT_9) + "-01 00:00:00";
        Calendar now = Calendar.getInstance( );
        Date nowDate = parse(startTime, DATE_FORMAT_2);
        now.setTime(nowDate);
        now.add(Calendar.DAY_OF_MONTH, -1);
        return format(now.getTime( ), DATE_FORMAT_1) + " 23:59:59";
    }

    /**
     * 得到某个日期几个月之前的日期
     *
     * @param month 月份数
     * @return
     */
    public static Date getTodayMonthBefore(int month) {

        return getMonthBefore(new Date( ), month);
    }

    /**
     * 得到某个日期的该月的起始时间 精确到00.00.00分
     *
     * @param date 日期
     * @return
     */
    public static Date getMonthStartTime(Date date) {
        String startTimeStr = format(date, DATE_FORMAT_9) + "-01 00:00:00";
        return parse(startTimeStr, DATE_FORMAT_2);
    }

    /**
     * 得到某个日期的该月的起始时间 精确到23:59:59分
     *
     * @param date 日期
     * @return
     */
    public static Date getMonthEndTime(Date date) {
        //获取Calendar
        Calendar calendar = Calendar.getInstance( );
        calendar.setTime(date);
        //设置日期为本月最大日期
        calendar.set(Calendar.DATE, calendar.getActualMaximum(calendar.DATE));
        String endTimeStr = format(calendar.getTime( ), DATE_FORMAT_1) + " 23:59:59";
        return parse(endTimeStr, DATE_FORMAT_2);
    }

    /**
     * 计算两个日期之间相差的天数
     *
     * @param smdate 起始日期
     * @param bdate  终止日期
     * @return 相差天数
     */
    public static int daysBetween(Date smdate, Date bdate) {

        smdate = parse(format(smdate, DATE_FORMAT_1), DATE_FORMAT_1);
        bdate = parse(format(bdate, DATE_FORMAT_1), DATE_FORMAT_1);
        Calendar cal = Calendar.getInstance( );
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis( );
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis( );
        long between_days = (time2 - time1) / (1000 * 3600 * 24);

        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 获取两个日期之间相差的月份数
     *
     * @param smdate 起始日期
     * @param bdate  终止日期
     * @return
     */
    public static int monthsBetween(Date smdate, Date bdate) {
        int result = 0;
        Calendar c1 = Calendar.getInstance( );
        Calendar c2 = Calendar.getInstance( );
        c1.setTime(smdate);
        c2.setTime(bdate);
        result = c2.get(Calendar.MONDAY) - c1.get(Calendar.MONTH);
        return result == 0 ? 1 : Math.abs(result);
    }

    public static int yearBetween(Date smdate, Date bdate) {
        int syear = Integer.parseInt(DateUtils.format(smdate, "yyyy"));
        int eyear = Integer.parseInt(DateUtils.format(bdate, "yyyy"));
        return eyear - syear;
    }

    public static int getHour(Date date) {
        Calendar calendar = Calendar.getInstance( );
        calendar.setTime(date);
        return calendar.get(Calendar.HOUR_OF_DAY);
    }


    public static void main(String[] args) {

    }
}

